/**
 * 🎯 Aperture 动画工具库
 *
 * 提供苹果风格的微交互动画函数
 */

// ===== 动画配置 =====
export const ANIMATION_DURATION = {
  FAST: 150,
  NORMAL: 250,
  SLOW: 350,
  EXTRA_SLOW: 500
} as const

export const ANIMATION_EASING = {
  EASE_OUT: 'cubic-bezier(0.25, 0.8, 0.25, 1)',
  EASE_IN_OUT: 'cubic-bezier(0.4, 0, 0.2, 1)',
  SPRING: 'cubic-bezier(0.175, 0.885, 0.32, 1.275)',
  BOUNCE: 'cubic-bezier(0.68, -0.55, 0.265, 1.55)'
} as const

// ===== 动画类 =====
export const ANIMATION_CLASSES = {
  FADE_IN_UP: 'aperture-fade-in-up',
  FADE_IN: 'aperture-fade-in',
  SLIDE_IN_RIGHT: 'aperture-slide-in-right',
  SLIDE_IN_LEFT: 'aperture-slide-in-left',
  PULSE: 'aperture-pulse',
  BOUNCE: 'aperture-bounce',
  SHAKE: 'aperture-shake'
} as const

// ===== 动画函数 =====

/**
 * 添加CSS动画类到元素
 */
export function addAnimationClass(element: HTMLElement, className: string, duration?: number) {
  if (!element) return

  element.classList.add(className)

  if (duration) {
    element.style.animationDuration = `${duration}ms`
  }

  // 动画结束后移除类
  const handleAnimationEnd = () => {
    element.classList.remove(className)
    element.removeEventListener('animationend', handleAnimationEnd)
  }

  element.addEventListener('animationend', handleAnimationEnd)
}

/**
 * 创建弹性缩放动画
 */
export function createBounceScale(element: HTMLElement, scale: number = 1.05) {
  if (!element) return

  element.style.transform = `scale(${scale})`
  element.style.transition = `transform ${ANIMATION_DURATION.NORMAL}ms ${ANIMATION_EASING.SPRING}`

  setTimeout(() => {
    element.style.transform = 'scale(1)'
  }, ANIMATION_DURATION.NORMAL)
}

/**
 * 创建震动效果
 */
export function createShake(element: HTMLElement) {
  if (!element) return

  element.style.animation = `shake ${ANIMATION_DURATION.SLOW}ms ${ANIMATION_EASING.EASE_OUT}`

  setTimeout(() => {
    element.style.animation = ''
  }, ANIMATION_DURATION.SLOW)
}

/**
 * 创建渐变动画
 */
export function createMorphTransition(
  element: HTMLElement,
  fromStyles: Partial<CSSStyleDeclaration>,
  toStyles: Partial<CSSStyleDeclaration>,
  duration: number = ANIMATION_DURATION.NORMAL
) {
  if (!element) return

  // 设置初始样式
  Object.assign(element.style, fromStyles)

  // 强制重排
  element.offsetHeight

  // 应用过渡
  element.style.transition = `all ${duration}ms ${ANIMATION_EASING.EASE_OUT}`

  // 应用目标样式
  Object.assign(element.style, toStyles)

  // 清理过渡
  setTimeout(() => {
    element.style.transition = ''
  }, duration)
}

/**
 * 创建连续波纹效果
 */
export function createRipple(element: HTMLElement, event: MouseEvent) {
  if (!element) return

  const rect = element.getBoundingClientRect()
  const size = Math.max(rect.width, rect.height)
  const x = event.clientX - rect.left - size / 2
  const y = event.clientY - rect.top - size / 2

  const ripple = document.createElement('span')
  ripple.style.cssText = `
    position: absolute;
    width: ${size}px;
    height: ${size}px;
    left: ${x}px;
    top: ${y}px;
    background: rgba(255, 255, 255, 0.3);
    border-radius: 50%;
    transform: scale(0);
    animation: ripple ${ANIMATION_DURATION.SLOW}ms ${ANIMATION_EASING.EASE_OUT};
    pointer-events: none;
  `

  element.style.position = 'relative'
  element.style.overflow = 'hidden'
  element.appendChild(ripple)

  setTimeout(() => {
    if (ripple.parentNode) {
      ripple.parentNode.removeChild(ripple)
    }
  }, ANIMATION_DURATION.SLOW)
}

/**
 * 创建打字机效果
 */
export function createTypewriterEffect(
  element: HTMLElement,
  text: string,
  speed: number = 50,
  callback?: () => void
) {
  if (!element) return

  element.textContent = ''
  let index = 0

  const typeNextChar = () => {
    if (index < text.length) {
      element.textContent += text[index]
      index++
      setTimeout(typeNextChar, speed)
    } else if (callback) {
      callback()
    }
  }

  typeNextChar()
}

/**
 * 创建数字递增动画
 */
export function createCountUpAnimation(
  element: HTMLElement,
  start: number,
  end: number,
  duration: number = 1000,
  callback?: (value: number) => void
) {
  if (!element) return

  const startTime = performance.now()
  const difference = end - start

  const updateCount = (currentTime: number) => {
    const elapsed = currentTime - startTime
    const progress = Math.min(elapsed / duration, 1)

    // 使用缓动函数
    const easeProgress = 1 - Math.pow(1 - progress, 3)
    const currentValue = Math.floor(start + difference * easeProgress)

    element.textContent = currentValue.toString()

    if (callback) {
      callback(currentValue)
    }

    if (progress < 1) {
      requestAnimationFrame(updateCount)
    }
  }

  requestAnimationFrame(updateCount)
}

/**
 * 创建滚动显示动画
 */
export function createScrollReveal(elements: HTMLElement[], options?: {
  threshold?: number
  rootMargin?: string
  delay?: number
}) {
  const {
    threshold = 0.1,
    rootMargin = '0px',
    delay = 0
  } = options || {}

  const observer = new IntersectionObserver((entries) => {
    entries.forEach((entry, index) => {
      if (entry.isIntersecting) {
        setTimeout(() => {
          entry.target.classList.add(ANIMATION_CLASSES.FADE_IN_UP)
        }, delay * index)

        observer.unobserve(entry.target)
      }
    })
  }, { threshold, rootMargin })

  elements.forEach(element => {
    if (element) {
      element.style.opacity = '0'
      element.style.transform = 'translateY(20px)'
      observer.observe(element)
    }
  })

  return observer
}

/**
 * 创建加载动画序列
 */
export function createLoadingSequence(elements: HTMLElement[], interval: number = 200) {
  elements.forEach((element, index) => {
    if (!element) return

    element.style.opacity = '0'

    setTimeout(() => {
      element.style.opacity = '1'
      element.style.animation = `fadeInUp ${ANIMATION_DURATION.NORMAL}ms ${ANIMATION_EASING.EASE_OUT}`
    }, index * interval)
  })
}

// ===== CSS动画定义 =====
export const ANIMATION_CSS = `
@keyframes shake {
  0%, 100% { transform: translateX(0); }
  10%, 30%, 50%, 70%, 90% { transform: translateX(-2px); }
  20%, 40%, 60%, 80% { transform: translateX(2px); }
}

@keyframes bounce {
  0%, 20%, 53%, 80%, 100% { transform: translateY(0); }
  40%, 43% { transform: translateY(-8px); }
  70% { transform: translateY(-4px); }
  90% { transform: translateY(-2px); }
}

@keyframes ripple {
  to {
    transform: scale(4);
    opacity: 0;
  }
}

@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes slideInRight {
  from {
    opacity: 0;
    transform: translateX(20px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

@keyframes slideInLeft {
  from {
    opacity: 0;
    transform: translateX(-20px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.5; }
}

.aperture-fade-in-up {
  animation: fadeInUp 350ms cubic-bezier(0.25, 0.8, 0.25, 1);
}

.aperture-fade-in {
  animation: fadeIn 250ms cubic-bezier(0.25, 0.8, 0.25, 1);
}

.aperture-slide-in-right {
  animation: slideInRight 350ms cubic-bezier(0.25, 0.8, 0.25, 1);
}

.aperture-slide-in-left {
  animation: slideInLeft 350ms cubic-bezier(0.25, 0.8, 0.25, 1);
}

.aperture-pulse {
  animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}

.aperture-bounce {
  animation: bounce 500ms cubic-bezier(0.68, -0.55, 0.265, 1.55);
}

.aperture-shake {
  animation: shake 350ms cubic-bezier(0.25, 0.8, 0.25, 1);
}
`

// ===== 工具函数 =====

/**
 * 检查是否支持动画
 */
export function supportsAnimations() {
  return !window.matchMedia('(prefers-reduced-motion: reduce)').matches
}

/**
 * 创建防抖动画函数
 */
export function debounceAnimation(fn: Function, delay: number) {
  let timeoutId: NodeJS.Timeout
  return (...args: any[]) => {
    clearTimeout(timeoutId)
    timeoutId = setTimeout(() => fn(...args), delay)
  }
}

/**
 * 创建节流动画函数
 */
export function throttleAnimation(fn: Function, limit: number) {
  let inThrottle: boolean
  return (...args: any[]) => {
    if (!inThrottle) {
      fn(...args)
      inThrottle = true
      setTimeout(() => inThrottle = false, limit)
    }
  }
}